package andrei.mower2.io.file;

import static org.junit.Assert.assertEquals;

import java.io.IOException;

import org.junit.Test;

import andrei.mower2.business.Mower.Command;
import andrei.mower2.business.MowerVector;
import andrei.mower2.business.Position;
import andrei.mower2.business.Mower.Direction;
import andrei.mower2.io.MowerInputReader;
import andrei.mower2.io.exceptions.MissingLawnCornerException;
import andrei.mower2.io.exceptions.UnparsableCommandException;
import andrei.mower2.io.exceptions.UnparsableLawnCornerException;
import andrei.mower2.io.exceptions.UnparsableMowerStartVectorException;
import andrei.mower2.utils.TestUtils;
import andrei.mower2.utils.MockUtils;

public class MowerFileInputReaderIT {

	@Test
	public void getLawnCornerTest() throws IOException {
		String fileContent = "1 2";
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		Position position = reader.getLawnCorner();
		assertEquals(1, position.x);
		assertEquals(2, position.y);
	}
	
	@Test(expected = MissingLawnCornerException.class)
	public void getLawnCornerMissingTest() throws IOException {
		String fileContent = "";
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
	}
	
	@Test(expected = UnparsableLawnCornerException.class)
	public void getLawnCornerUnparsableTest() throws IOException {
		String fileContent = "1 abc";
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
	}
	
	@Test
	public void nextStartVectorTest() throws IOException, UnparsableMowerStartVectorException {
		String fileContent = TestUtils.generateFileContent(
				"5 5",
				"3 4 N",
				"",
				"5 6 S",
				"");
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
		MowerVector vector = reader.nextStartVector();
		assertEquals(3, vector.position.x);
		assertEquals(4, vector.position.y);
		assertEquals(Direction.N, vector.direction);
		
		vector = reader.nextStartVector();
		assertEquals(5, vector.position.x);
		assertEquals(6, vector.position.y);
		assertEquals(Direction.S, vector.direction);
	}
	
	@Test(expected = UnparsableMowerStartVectorException.class)
	public void nextStartVectorUnparsableTest() throws IOException, UnparsableMowerStartVectorException {
		String fileContent = TestUtils.generateFileContent(
				"5 5",
				"3 4 N",
				"",
				"5 bla S",
				"");
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
		reader.nextStartVector();
		reader.nextStartVector();
	}
	
	@Test
	public void nextStartVectorSkipUnparsableTest() throws IOException, UnparsableMowerStartVectorException {
		String fileContent = TestUtils.generateFileContent(
				"5 5",
				"3 bla N",
				"",
				"5 6 S",
				"");
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
		Throwable t = null;
		try {
			reader.nextStartVector();
		} catch(Throwable th) {
			t = th;
		}	
		assertEquals(UnparsableMowerStartVectorException.class, t.getClass());		
		MowerVector vector = reader.nextStartVector();
		assertEquals(5, vector.position.x);
		assertEquals(6, vector.position.y);
		assertEquals(Direction.S, vector.direction);
	}
	
	@Test
	public void nextCommandTest() throws UnparsableCommandException, IOException {
		String fileContent = TestUtils.generateFileContent(
				"5 5",
				"0 0 N",
				"DGA");
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
		Command command = reader.nextCommand();
		assertEquals(Command.D, command);
		command = reader.nextCommand();
		assertEquals(Command.G, command);
		command = reader.nextCommand();
		assertEquals(Command.A, command);
	}
	
	@Test(expected = UnparsableCommandException.class)
	public void nextCommandUnparsableTest() throws UnparsableCommandException, IOException {
		String fileContent = TestUtils.generateFileContent(
				"5 5",
				"0 0 N",
				"DblaA");
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
		reader.nextCommand();
		reader.nextCommand();
	}
	
	@Test
	public void nextCommandUnparsableSkipTest() throws UnparsableCommandException, IOException {
		String fileContent = TestUtils.generateFileContent(
				"5 5",
				"0 0 N",
				"D?A");
		MowerInputReader reader = MockUtils.getMowerStringInputReader(fileContent);
		reader.getLawnCorner();
		Command command = reader.nextCommand();
		assertEquals(Command.D, command);
		Throwable t = null;
		try {
			command = reader.nextCommand();
		} catch(Throwable th) {
			t = th;
		}
		assertEquals(UnparsableCommandException.class, t.getClass());
		command = reader.nextCommand();
		assertEquals(Command.A, command);
	}
}
